﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using SchemaMonitor;
using SchemaMonitor.html;
using Framework;
using System.Web.Services;
using System.IO;
using System.Drawing;
using System.Web.UI.HtmlControls;
using System.Web.Script.Services;
using System.Text;

public partial class PhotoHash : System.Web.UI.Page
{

    #region Querystring
    public int Show { get { return CWeb.RequestInt("show", RblSelectedValue); } }
    public int ChapterId { get { return CWeb.RequestInt("chapterId", CSession.ChapterId); } }
    public int TagId { get { return CWeb.RequestInt("tagId", CSession.TagId); } }
	public int FilterByTagId { get { return CWeb.RequestInt("filterByTagId", CSession.FilterByHasTagId); } }
	public Guid MD5 { get { return CWeb.RequestGuid("md5"); } }
    #endregion

    #region Session
    public EShow RblSelectedValue_ { get { return (EShow)RblSelectedValue; } set { RblSelectedValue = (int)value; } }
    public int RblSelectedValue
    {
        get { return CSession.GetInt("PhotosHash.RblSelectedValue", 1); }
        set { CSession.Set("PhotosHash.RblSelectedValue", value); }
    }

    public static List<Guid> SelectedGuids
    {
        get { return (List<Guid>)CSession.GetObj("PhotosHash.SelectedGuids"); }
        set { CSession.Set("PhotosHash.SelectedGuids", value); }
    }
    #endregion

    #region Data
    public CChapter Chapter { get { return CChapter.Cache.GetById(ChapterId); } }
    public CMetaTag Tag { get { return CMetaTag.Cache.GetById(TagId); } }
    public CPhotoHash Photo { get { return CPhotoHash.Cache.GetById(MD5); } }
    #endregion

    #region old
    public List<SchemaMonitor.html.CPhoto> Biggest()
    {
        List<SchemaMonitor.html.CPhoto> biggest = null;
        foreach (var i in this.PhotosFromHtml.Keys)
        {
            var photos = this.PhotosFromHtml[i];
            if (null == biggest || biggest.Count < photos.Count)
                biggest = photos;
        }
        return biggest;
    }
    public Dictionary<long, List<SchemaMonitor.html.CPhoto>> PhotosFromHtml
    {
        get
        {
            var key = "Photos.FromHtml";
            var dict = (Dictionary<long, List<SchemaMonitor.html.CPhoto>>)CSession.Get(key);
            if (null == dict)
            {
                dict = new Dictionary<long, List<SchemaMonitor.html.CPhoto>>();
                foreach (var i in CHtml.AlbumIds())
                    dict.Add(i, CHtml.LoadPhotos(i));
                CSession.Set(key, dict);
            }
            return dict;
        }
    }
	#endregion

	#region Ajax WebMEthods
	[WebMethod(EnableSession = true)]
    //[ScriptMethod(UseHttpGet = true)]
    public static string[] Toggle(string g)
    {
        Guid md5 = new Guid(g);
        if (SelectedGuids.Contains(md5))
            SelectedGuids.Remove(md5);
        else
            SelectedGuids.Add(md5);
        return new string[] { CUtilities.CountSummary(SelectedGuids, "image", "none"), DisplaySelected() };
    }
    [WebMethod(EnableSession = true)]
    //[ScriptMethod(UseHttpGet = true)]
    public static string GetSelected()
    {
        return DisplaySelected();
    }
	#endregion

	#region Page Events
	protected void Page_Init(object sender, EventArgs e)
    {
		if (null == SelectedGuids)
			SelectedGuids = new List<Guid>();

		//DETAILS page
		if (null != Photo)
        {
            DisplayPhoto();
            return;
        }

        //Actions
        var show = RblSelectedValue_;
        var addId = CWeb.RequestGuid("add");
        if (addId != Guid.Empty) Add(show, addId);

        var remId = CWeb.RequestGuid("rem");
        if (remId != Guid.Empty) Remove(show, remId);

        //Auto-tab
        if (CWeb.RequestInt("tagId") > 0)
            RblSelectedValue_ = EShow.ForTag;
        if (CWeb.RequestInt("chapterId") > 0)
            RblSelectedValue_ = EShow.ForPost;

		//Store session
		if (TagId > 0)
			CSession.TagId = TagId;
		if (FilterByTagId > 0)
			CSession.FilterByHasTagId = FilterByTagId;


		//Selected
		lblSelected.Text = CUtilities.CountSummary(SelectedGuids, "image", "No Images Selected (click to select)");
        litSelImgs.Text = DisplaySelected();
        btnAddSelected.Enabled = SelectedGuids.Count > 0 && (show == EShow.ForTag || show == EShow.XRated || show == EShow.Laptop || show == EShow.Delete);
        btnClearBucket.Enabled = btnAddSelected.Enabled;
        pnlSelected.Visible = (show != EShow.All);
        if (pnlSelected.Visible)
        {
            ddTagForSelected.DataSource = CTagType.Cache.FB_Album.MetaTags;
            ddTagForSelected.DataBind();
            CDropdown.BlankItem(ddTagForSelected, "-- Select Tag --");
        }



        //session state: dropdowns
        foreach (var i in CTagType.Cache.FB_Filters.MetaTags)
            CDropdown.Add(ddHasTag, "*" + i.NameAndCount, i.TagId);
        foreach (var i in CTagType.Cache.FB_Album.MetaTags)
            CDropdown.Add(ddHasTag, i.NameAndCount, i.TagId);
        CDropdown.BlankItem(ddHasTag, "-- Having Tag --");
        CDropdown.SetValue(ddHasTag, CSession.FilterByHasTagId);

        foreach (var i in CTagType.Cache.FB_Filters.MetaTags)
            CDropdown.Add(ddNotTag, "*" + i.NameAndCount, i.TagId);
        foreach (var i in CTagType.Cache.FB_Album.MetaTags)
            CDropdown.Add(ddNotTag, i.NameAndCount, i.TagId);
        CDropdown.BlankItem(ddNotTag, "-- Except Tag --");
        CDropdown.SetValue(ddNotTag, CSession.FilterByNotTagId);

        CDropdown.AddEnums(ddSortBy, typeof(ESortBy));
        CDropdown.SetValue(ddSortBy, CSession.SortBy);

        //session state: checkboxes
        chkNoTag.Checked = CSession.FilterByNoTag;
        chkNoPost.Checked = CSession.FilterByNoPost;
        chkCaption.Checked = CSession.FilterByHasCaption;


        //panels
        pnlChapter.Visible = show == EShow.ForPost;
        pnlTag.Visible     = show == EShow.ForTag;



        //data
        var all = CPhotoHash.Cache;
        var lhs = all;
        var rhs = new CPhotoHashList(0);
        ApplyFilters(show, ref lhs, ref rhs);

        //Paging
        var pi = ctrlPaging1.Info;
        var page = ctrlPaging1.Display(lhs);
        ctrlPaging2.Info = pi;


        //Display
        BalanceLeftRight(lhs, rhs);
        if (show != EShow.All && show != EShow.Select)
        {
			//lhs
            if (lhs.Count > 0)
                ctrlLhs.Display(page, SelectedGuids, pi, show, true);
            else
                colLHS.Visible = false;

			//rhs
            if (rhs.Count > 0)
            {
                var pi2 = ctrlPagingRhs1.Info;
                var pageRhs = ctrlPagingRhs1.Display(rhs);  //page to show
                ctrlPagingRhs2.Info = pi2;
                ctrlRhs.Display(pageRhs, SelectedGuids, pi2, show, false);
                colTop.ColSpan = 2;
                colBottom.Visible = true;
            }
        }
		else
		{
			//lhs only
            ctrlLhs.Display(page, SelectedGuids, pi, show);
		}

    }
	#endregion



	#region Click to Add/Rem
	public void Add(EShow show, Guid g)
    {
        switch (show)
        {
            //AJAX
            case EShow.Select:
                if (!SelectedGuids.Contains(g))
                    SelectedGuids.Add(g);
                //Response.Redirect(string.Concat(CSitemap.PhotoHash(show), "&p=", CWeb.RequestInt("p", 1), "&pageSize=", CWeb.RequestInt("pageSize", 200)));
                break;


            //COMMAND
            case EShow.ForPost:
                Add(g, this.Chapter);
                break;
            
            case EShow.ForTag:
                Add(g, this.Tag);
                break;

            case EShow.XRated:
                Add_O2O(g, EImgBucket.XRated);
                break;

            case EShow.Delete:
                Add_O2O(g, EImgBucket.Deleted);
                break;

			case EShow.Laptop:
				Add_O2O(g, EImgBucket.Laptop);
				break;
		}
    }

    public void Add(Guid g, CMetaTag t)
    {
        var ph = CPhotoHash.Cache.GetById(g);
        ph.AddLabel(t);
        if (ph.Bucket == EImgBucket.Laptop)
            ph.Bucket = EImgBucket.None;
    }
    public void Add_O2O(Guid g, EImgBucket bucket)
    {
        CPhotoHash.Cache.GetById(g).Bucket = bucket;
    }
    public void Add(Guid g, CChapter C)
    {
        var cpp = CChapterPicture.Cache.GetByChapterId(C.ChapterId).GetByPhotoMD5(g);
        if (cpp.Count > 0)
            return;

        var cp = new CChapterPicture();
        cp.PictureChapterId = C.ChapterId;
        cp.PicturePhotoMD5 = g;
        cp.Save();
    }


    public void Remove(EShow show, Guid g)
    {
        switch (show)
        {
            case EShow.Select:
                if (SelectedGuids.Contains(g))
                    SelectedGuids.Remove(g);
				//Response.Redirect(string.Concat(CSitemap.PhotoHash(show), "&p=", CWeb.RequestInt("p", 1), "&pageSize=", CWeb.RequestInt("pageSize", 200)));
				break;

            case EShow.ForPost:
                Remove(g, this.Chapter);
                break;

            case EShow.ForTag:
                Remove(g, this.Tag);
                break;

            case EShow.XRated:
                Remove_O2O(g, CMetaTag.Cache.XRated);
                break;

            case EShow.Delete:
                Remove_O2O(g, CMetaTag.Cache.Delete);
                break;

			case EShow.Laptop:
				Remove_O2O(g, CMetaTag.Cache.Laptop);
				break;
		}
	}

    public void Remove(Guid g, CMetaTag t)
    {
        var lbl = CLabel.Cache.GetById(g, t.TagId);
        if (null != lbl)
            lbl.Delete();
    }
    public void Remove_O2O(Guid g, CMetaTag t)
    {
        var lbl = CLabel_OneToOne.Cache.GetById(g, t.TagTypeId);
        if (null != lbl)
            lbl.Delete();
    }
    public void Remove(Guid g, CChapter C)
    {
        var cpp = CChapterPicture.Cache.GetByChapterId(C.ChapterId).GetByPhotoMD5(g);
        if (cpp.Count > 0)
            cpp[0].Delete();
    }
    #endregion

    #region Display
    private static string DisplaySelected()
    {
        var sb = new StringBuilder();
        if (!string.IsNullOrEmpty(CSession.PageMessage))
        {
            sb.Append(CSession.PageMessage).Append("<br/>");
            CSession.PageMessage = null; ;
        }
        foreach (var i in SelectedGuids)
            sb.Append("<img src='../../").Append(CSitemap.Photo(i).Substring(2)).Append("' height='90' onclick=\"AddOrRemove('").Append(i).Append("','d").Append(i.ToString().Substring(0, 6)).Append("')\" />");
        return sb.ToString();
    }
    private void ApplyFilters(EShow sel, ref CPhotoHashList lhs, ref CPhotoHashList rhs)
    {
        var nopost = lhs.Unused_;
        var noTags = lhs.Untagged_;
        var caption = lhs.Caption;

        //Counts
        rbl.Items[(int)EShow.All   ].Text = CUtilities.NameAndCount(rbl.Items[(int)EShow.All   ].Text, lhs);
		rbl.Items[(int)EShow.XRated].Text = CUtilities.NameAndCount(rbl.Items[(int)EShow.XRated].Text, CMetaTag.Cache.XRated.PhotoHashsO2O);
		rbl.Items[(int)EShow.Delete].Text = CUtilities.NameAndCount(rbl.Items[(int)EShow.Delete].Text, CMetaTag.Cache.Delete.PhotoHashsO2O);
		rbl.Items[(int)EShow.Laptop].Text = CUtilities.NameAndCount(rbl.Items[(int)EShow.Laptop].Text, CMetaTag.Cache.Laptop.PhotoHashsO2O);

        //Counts = menu
        var repeatCount = new CImageMatching().SelectCount();
		menu.Items[(int)EMenu.Repeats].Text = CUtilities.NameAndCount(menu.Items[(int)EMenu.Repeats].Text, repeatCount);

        //Counts - checkboxes
        chkCaption.Text = CUtilities.NameAndCount(chkCaption.Text, caption);
        chkNoPost.Text = CUtilities.NameAndCount(chkNoPost.Text, nopost);
        chkNoTag.Text = CUtilities.NameAndCount(chkNoTag.Text, noTags);
        chkXRated.Text = CUtilities.NameAndCount(chkXRated.Text, CMetaTag.Cache.XRated.PhotoHashsO2O);
        chkDeleted.Text = CUtilities.NameAndCount(chkDeleted.Text, CMetaTag.Cache.Delete.PhotoHashsO2O);


        chkXRated.Checked = CSession.ShowingXRated;
        chkDeleted.Checked = CSession.ShowingDeleted;
        chkNoTag.Checked = CSession.FilterByNoTag;
        chkNoPost.Checked = CSession.FilterByNoPost;

        //Tab
        CDropdown.SetValue(rbl, RblSelectedValue);

		//Bad combos
		if (sel == EShow.Delete)
		{
            chkDeleted.Enabled = false;
            chkDeleted.Checked = true;
            CSession.ShowingDeleted = true;
		}
        if (sel == EShow.XRated)
        {
            chkXRated.Enabled = false;
            chkXRated.Checked = true;
            CSession.ShowingXRated = true;
        }
        if (CSession.FilterByHasTagId > 0 || CSession.FilterByNotTagId > 0)
        {
            var tag = CMetaTag.Cache.GetById(CSession.FilterByHasTagId);
            lhs = lhs.GetByTag(tag);
            chkNoTag.Checked = false;
            CSession.FilterByNoTag = false;
        }


        //Filters - Auto-hide Deleted, X-Rated
        if (!CSession.ShowingDeleted)   lhs = lhs.Except(CMetaTag.Cache.Delete.PhotoHashsO2O);
        if (!CSession.ShowingXRated)    lhs = lhs.Except(CMetaTag.Cache.XRated.PhotoHashsO2O);

        //Filters - NoTag/NoPost
        if (CSession.FilterByNoPost)     lhs = lhs.Unused;
        if (CSession.FilterByNoTag)      lhs = lhs.Untagged;
        if (CSession.FilterByHasCaption) lhs = lhs.Caption_;

        //Filters - tag
        if (CSession.FilterByHasTagId > 0)
        {
			var tag = CMetaTag.Cache.GetById(CSession.FilterByHasTagId);
			lhs = lhs.GetByTag(tag);
            chkRemoveTag.Visible = true;
            chkRemoveTag.Text += CUtilities.Truncate(tag.TagName, 15);
        }
        if (CSession.FilterByNotTagId > 0)
        {
            var tag = CMetaTag.Cache.GetById(CSession.FilterByHasTagId);
            lhs = lhs.Except(lhs.GetByTag(tag));
        }


        //Sort Order
        if (CSession.Random)
            lhs = CSession.Shuffled((CPhotoHashList)lhs);
        else if (CSession.ByDate)
            lhs = lhs.SortByNearest();
        else
            lhs = lhs.SortByLeastTagsThenCreated();


        //Instructions
        if (sel == EShow.All)
        {
            lblLhs.Text = "Click to EDIT Image (tags, etc)";
        }
        else if (sel == EShow.Select || sel == EShow.Delete || sel == EShow.XRated || sel == EShow.Laptop)
        {
            lblLhs.Text = "Click to SELECT Image (tags, etc)";
        }


        //One-to-Many
        if (sel == EShow.ForPost)
        {
            ddChapter.Visible = true;
            ddChapter.DataSource = CChapter.Cache;
            ddChapter.DataBind();
            CDropdown.SetValue(ddChapter, ChapterId);

            lhs = lhs.GetByIds(Chapter.ChapterPictures.Photos.Ids);
            rhs = lhs.Except(lhs);

            rbl.Items[RblSelectedValue].Text = CUtilities.NameAndCount(rbl.Items[RblSelectedValue].Text, lhs);
        }
        else if (sel == EShow.ForTag)
        {
            var tt = CTagType.Cache.FB_Album;

            ddTag.Visible = true;
            ddTag.DataSource = tt.MetaTags;
            ddTag.DataBind();
            CDropdown.BlankItem(ddTag, "-- Select Tag --");
            CDropdown.SetValue(ddTag, TagId);
            btnAddTag.Visible = true;
            txtName.Visible = true;

			//Filter
            if (null == Tag)
				lhs = new CPhotoHashList();

			//Split
			rhs = lhs;
	        lhs = null == Tag ? new CPhotoHashList() : lhs.GetByLabel(Tag);
			rhs = rhs.Except(lhs);

			//Show count
            rbl.Items[RblSelectedValue].Text = CUtilities.NameAndCount(rbl.Items[RblSelectedValue].Text, lhs);

        }

        //One-to-One tags
        else if (sel == EShow.XRated)
        {
            lhs = lhs.GetByLabel(CMetaTag.Cache.XRated);
        }
        else if (sel == EShow.Delete)
		{
			lhs = lhs.GetByLabel(CMetaTag.Cache.Delete);
		}
		else if (sel == EShow.Laptop)
		{
			lhs = lhs.GetByLabel(CMetaTag.Cache.Laptop);
        }

        btnRemoveLaptopTag.Visible    = (sel == EShow.Laptop);
        btnRemoveLaptopTagAll.Visible = (sel == EShow.Laptop);

    }
    private void BalanceLeftRight(CPhotoHashList lhs, CPhotoHashList rhs)
    {
        if (rhs.Count > lhs.Count)
        {
            ctrlLhs.Columns = 4;
            ctrlRhs.Columns = 6;
            if (rhs.Count > 10 * lhs.Count)
            {
                ctrlLhs.Columns = 3;
                ctrlRhs.Columns = 7;
            }
            if (lhs.Count < 10)
            {
                ctrlLhs.Columns = 2;
                ctrlRhs.Columns = 8;
            }
            if (lhs.Count == 0)
            {
                ctrlLhs.Columns = 1;
                ctrlRhs.Columns = 9;
            }
        }
        else
        {
            ctrlLhs.Columns = 6;
            ctrlRhs.Columns = 4;
            if (lhs.Count > 10 * rhs.Count)
            {
                ctrlLhs.Columns = 7;
                ctrlRhs.Columns = 3;
            }
            if (rhs.Count < 10)
            {
                ctrlLhs.Columns = 8;
                ctrlRhs.Columns = 2;
            }
            if (rhs.Count == 0)
            {
                ctrlLhs.Columns = 9;
                ctrlRhs.Columns = 1;
            }

        }
    }
    #endregion

    #region Display - Single
    private void DisplayPhoto(int N = 20)
    {
        ddPage.DataSource = CChapter.Cache;
        ddPage.DataBind();
        CDropdown.BlankItem(ddPage);

        var tags = CMetaTag.Cache.OneToMany;
        if (tags.Count > 10)
            cbl.RepeatColumns = 2;
        cbl.DataSource = tags;
        cbl.DataBind();
        CDropdown.SetValues(cbl, Photo.MetaTags.Ids);

        foreach (var i in CTagType.Cache.OneToOne)
        {
            var rbl = new RadioButtonList();
            rbl.BackColor = Color.FromName("#f5f5f5");
            rbl.RepeatDirection = RepeatDirection.Horizontal;
            rbl.RepeatLayout = RepeatLayout.Flow;
            rbl.DataTextField = "NameAndCount";
            rbl.DataValueField = "TagId";
            rbl.DataSource = i.MetaTags;
            rbl.DataBind();
            CDropdown.BlankItem(rbl, "none");
            var o2o = Photo.MetaTagsO2O.GetByTypeId(i.TypeId);
            if (o2o.Count > 0)
                CDropdown.SetValue(rbl, o2o[0].TagId);
            else
                rbl.SelectedIndex = 0;
            rbl.ID = "type_" + i.TypeId;
            rbl.SelectedIndexChanged += Dd_SelectedIndexChanged;

            var div = new Panel();
            div.Style.Add("margin-bottom", "10px");

            var lbl = new Label();
            lbl.Text = i.TypeName + ":";
            lbl.Font.Bold = true;
            div.Controls.Add(lbl);

            div.Controls.Add(rbl);
            plhO2O.Controls.Add(div);
        }

        plhDetail.Visible = true;
        plhSearch.Visible = false;
        lblHeight.Text = CTextbox.SetNumber(Photo.PhotoHeight);
        lblWidth.Text = CTextbox.SetNumber(Photo.PhotoWidth);
        lblSize.Text = CUtilities.FileSize(Photo.PhotoSize);
        lblMD5.Text = CBinary.ToBase64(Photo.PhotoMd5.ToByteArray());
        lblMD5.NavigateUrl = CSitemap.PhotoHashAll();
        if (Guid.Empty != Photo.PhotoParentMD5)
        {
            lnkParent.Text = CBinary.ToBase64(Photo.PhotoParentMD5.ToByteArray());
            lnkParent.NavigateUrl = CSitemap.PhotoDetails(Photo.PhotoParentMD5);
        }
        var n = 1;
        if (Photo.PhotoWidth < 300)
            n = 2;
        if (Photo.PhotoWidth < 150)
            n = 3;
        var bmp = new System.Drawing.Bitmap(new MemoryStream(Photo.GetBlob()));
        if (bmp.Width != Photo.PhotoWidth && bmp.Height != Photo.PhotoHeight)
        {
            Photo.PhotoHeight = bmp.Height;
            Photo.PhotoWidth = bmp.Width;
            Photo.Save();
            img.Dispose();
        }


        img.Width = n * Photo.PhotoWidth;
        img.Height = n * Photo.PhotoHeight;
        img.ImageUrl = CSitemap.Photo(MD5);
        lnkImg.NavigateUrl = img.ImageUrl;
        lblCreated.Text = CUtilities.Timespan(Photo.PhotoCreated);
        lblCreated.ToolTip = CUtilities.LongDateTime(Photo.PhotoCreated);

        //Before/After
        var list = CPhotoHash.Cache.SortByNearest();

        var index = list.IndexOf(Photo);
        var minusN = index - N;
        var plusN = index + N;
        if (minusN < 0) minusN = 0;
        if (plusN >= list.Count) plusN = list.Count - 1;

        var before = new CPhotoHashList();
        for (var i = minusN; i < index; i++)
            before.Add(list[i]);
        ctrlBefore.Display(before);

        var after = new CPhotoHashList();
        for (var i = index + 1; i <= plusN; i++)
            after.Add(list[i]);
        ctrlAfter.Display(after);

        //tags
        /*
		var tags = new CMetaTagList(CMetaTag.Cache).OneToMany;
		foreach (var i in Photo.MetaTags)
		{
			tags.Remove(i);
			var lnk = new LinkButton();
			lnk.Style.Add("margin-right", "5px");
			lnk.Text = i.TagName;
			lnk.CommandArgument = i.TagId.ToString();
			lnk.OnClientClick = "return confirm('Remove this tag?')";
			plhTags.Controls.Add(lnk);
			lnk.Click += LnkRemoveTag_Click;
		}

		//Remaining Tags 
		foreach (var i in tags)
		{
			
			var lnk = new LinkButton();
			lnk.Style.Add("margin-right", "5px");
			lnk.Text = i.TagName;
			lnk.CommandArgument = i.TagId.ToString();
			lnk.OnClientClick = "return confirm('Add this tag?')";
			plhTagsLeft.Controls.Add(lnk);
			lnk.Click += LnkAddTag_Click;
		}
		*/

        //Pages
        foreach (var i in Photo.Chapters)
        {
            var lnk = new HyperLink();
            lnk.NavigateUrl = CSitemap.ChapterEdit(i.ChapterId);
            lnk.ToolTip = i.FullName;
            lnk.Text = CUtilities.Truncate(lnk.ToolTip, 50);

            var div = new HtmlGenericControl("li");
            div.Controls.Add(lnk);
            plhPages.Controls.Add(div);
        }
    }

    private void Dd_SelectedIndexChanged(object sender, EventArgs e)
    {
        var dd = (DropDownList)sender;
        var typeId = int.Parse(dd.ID.Substring(dd.ID.IndexOf("type_") + 5));
        var tagId = CDropdown.GetInt(dd);
        if (int.MinValue == tagId)
            Photo.MetaTagsO2O.GetByTypeId(typeId).DeleteAll();
        else
        {
            var lbl = new CLabel_OneToOne();
            lbl.LabelGuid = Photo.PhotoMd5;
            lbl.LabelTagId = tagId;
            lbl.LabelTypeId = typeId;
            lbl.Save();
        }
    }

    #endregion


    #region Form Events

    private void LnkAddTag_Click(object sender, EventArgs e)
    {
        LinkButton btn = (LinkButton)sender;
        var tagId = int.Parse(btn.CommandArgument);
        var lbl = new CLabel();
        lbl.LabelTagId = tagId;
        lbl.LabelGuid = MD5;
        lbl.Save();
        Response.Redirect(Request.RawUrl);
    }

    private void LnkRemoveTag_Click(object sender, EventArgs e)
    {
        LinkButton btn = (LinkButton)sender;
        var tagId = int.Parse(btn.CommandArgument);
        foreach (var i in Photo.Labels)
            if (i.LabelTagId == tagId)
            {
                i.Delete();
                Response.Redirect(Request.RawUrl, true);
            }
    }

    protected void rbl_SelectedIndexChanged(object sender, EventArgs e)
    {
		CSession.FilterByHasTagId = int.MinValue;

        RblSelectedValue = CDropdown.GetInt(rbl);
        if (RblSelectedValue_ == EShow.ForPost)
            Response.Redirect(CSitemap.PhotoHash(CChapter.Cache[0].ChapterId));
        else if (RblSelectedValue_ == EShow.ForTag)
            Response.Redirect(CSitemap.PhotoHashForTag(CSession.TagId));
		else
			Response.Redirect(CSitemap.PhotoHash());
    }


    protected void ddChapter_SelectedIndexChanged(object sender, EventArgs e)
    {
        RblSelectedValue_ = EShow.ForPost;
        CSession.ChapterId = CDropdown.GetInt(ddChapter);
        Response.Redirect(CSitemap.PhotoHash(CSession.ChapterId));
    }

    protected void ddTag_SelectedIndexChanged(object sender, EventArgs e)
    {
        RblSelectedValue_ = EShow.ForTag;
        CSession.TagId = CDropdown.GetInt(ddTag);
        Response.Redirect(CSitemap.PhotoHashForTag(CSession.TagId));
    }

    protected void btnAddTag_Click(object sender, EventArgs e)
    {
        CMetaTag removeTag = null;
        if (chkRemoveTag.Checked)
            CMetaTag.Cache.GetById(CDropdown.GetInt(ddHasTag));

        //Read new tag
        bool isSelectionPage = false;
        string name = txtName.Text;
        if (txtName.Visible == false || string.IsNullOrEmpty(txtName.Text))
        {
            name = txtName2.Text;
            isSelectionPage = true;
        }
        if (name.Trim().Length == 0)
            return;

        var type = CTagType.Cache.FB_Album;
        var t = CMetaTag.Cache.GetOrCreate(name, type.TypeId);

        var skipped = 0;
        var tmp = new List<Guid>(SelectedGuids);
        foreach (var i in tmp)
        {
            var ph = CPhotoHash.Cache.GetById(i);
            if (!ph.AddLabel(t))
                skipped++;

            SelectedGuids.Remove(i);

            if (null != removeTag)
                ph.RemoveLabel(removeTag);
        }
        CSession.PageMessage = string.Concat("Added ", tmp.Count, skipped > 0 ? ", skipped=" + skipped : string.Empty, ". ", t.NameAndCount);

        Response.Redirect(isSelectionPage ? Request.RawUrl : CSitemap.PhotoHashForTag(t.TagId));
    }

    protected void btnAdd_Click(object sender, EventArgs e)
    {
        string s = txtTag.Text;
        if (s.Length == 0)
            return;

        var t = new CMetaTag();
        t.TagName = s;
        t.TagTypeId = CTagType.Cache.FB_Album.TypeId;
        t.Save();

        var l = new CLabel();
        l.LabelTagId = t.TagId;
        l.LabelGuid = MD5;
        l.Save();

        if (chkRemoveTag.Checked)
        {
            l = CLabel.Cache.GetById(MD5, CDropdown.GetInt(ddHasTag));
            if (null != l)
                l.Delete();
        }

        Response.Redirect(Request.RawUrl);
    }

    protected void menu_MenuItemClick(object sender, MenuEventArgs e)
    {
        var id = int.Parse(menu.SelectedValue);
        if (id <= 8)
            Response.Redirect(CSitemap.Home(id));

        if (id == (int)EMenu.Photos)
            Response.Redirect(CSitemap.PhotoHash(EShow.Select));

        if (id == (int)EMenu.Repeats)
            Response.Redirect(CSitemap.PhotoRepeats());
    }

    protected void cbl_SelectedIndexChanged(object sender, EventArgs e)
    {
        var p = this.Photo;
        var selected = p.Labels.MetaTags;
        foreach (ListItem i in cbl.Items)
        {
            var tagId = int.Parse(i.Value);
            if (i.Selected && !selected.Has(tagId))
            {
                var lbl = new CLabel();
                lbl.LabelGuid = p.PhotoMd5;
                lbl.LabelTagId = tagId;
                lbl.Save();
            }
            else if (!i.Selected && selected.Has(tagId))
                CLabel.Cache.GetById(p.PhotoMd5, tagId).Delete();
        }
        Response.Redirect(Request.RawUrl);
    }
    protected void btnAddSelected_Click(object sender, EventArgs e)
    {
        var s = (EShow)Show;
        switch (s)
        {
            case EShow.ForTag:
			case EShow.Laptop:
			case EShow.XRated:
			case EShow.Delete:
				while (SelectedGuids.Count > 0)
                {
                    Add(s, SelectedGuids[0]);
                    SelectedGuids.RemoveAt(0);
				}
				break;
        }
        Response.Redirect(Request.RawUrl);
    }


    protected void ddPage_SelectedIndexChanged(object sender, EventArgs e)
    {
        CSession.ChapterId = CDropdown.GetInt(ddPage);
        Response.Redirect(CSitemap.PhotoHash(CSession.ChapterId));
    }


    //Clear selection
    protected void btnClearBucket_Click(object sender, EventArgs e)
    {
        while (SelectedGuids.Count > 0)
        {
            CPhotoHash.Cache.GetById(SelectedGuids[0]).Bucket = EImgBucket.None;
            SelectedGuids.RemoveAt(0);
        }
        Response.Redirect(CSitemap.PhotoHash(CSession.ChapterId));
    }



    //Clear-cache
    protected void btnClearCache_Click(object sender, EventArgs e)
    {
        CCache.ClearAll();
        Response.Redirect(Request.RawUrl);
    }


    //Filter
    protected void chkFilter_CheckedChanged(object sender, EventArgs e)
    {
        CSession.FilterByNoTag = chkNoTag.Checked;
        CSession.FilterByNoPost = chkNoPost.Checked;
        CSession.FilterByHasCaption = chkCaption.Checked;
        CSession.ShowingXRated = chkXRated.Checked;
        CSession.ShowingDeleted = chkDeleted.Checked;

        Response.Redirect(Request.RawUrl);
    }
    protected void ddHasTag_SelectedIndexChanged(object sender, EventArgs e)
    {
        CSession.FilterByHasTagId = CDropdown.GetInt(ddHasTag);
        Response.Redirect(Request.RawUrl);
    }
    protected void ddNotTag_SelectedIndexChanged(object sender, EventArgs e)
    {
        CSession.FilterByHasTagId = CDropdown.GetInt(ddHasTag);
        Response.Redirect(Request.RawUrl);
    }

    //Sort
    protected void ddSortBy_SelectedIndexChanged(object sender, EventArgs e)
    {
        CSession.SortBy = CDropdown.GetInt(ddSortBy);
        if (CSession.SortBy_ == ESortBy.Random)
            CSession.Shuffle();        
        Response.Redirect(Request.RawUrl);
    }


    //Label (many)
    protected void ddTagForSelected_SelectedIndexChanged(object sender, EventArgs e)
    {
        CMetaTag removeTag = null;
        if (chkRemoveTag.Checked)
            CMetaTag.Cache.GetById(CDropdown.GetInt(ddHasTag));

        var tagId = CDropdown.GetInt(ddTagForSelected);
        var temp = new List<Guid>(SelectedGuids);
        int count = 0;
        int removed = 0;
        foreach (var i in temp)
        {
            var ph = CPhotoHash.Cache.GetById(i);

            if (ph.AddLabel(tagId))
                count++;

            SelectedGuids.Remove(i);

            if (null != removeTag)
                if (ph.RemoveLabel(removeTag))
                    removed++;
        }

        CSession.PageMessage = string.Concat(temp.Count + " selected: ", count, " added, ", temp.Count - count, " skipped, ", removed, " removed");

        Response.Redirect(Request.RawUrl);
    }


    //Classify (one)
    protected void btnRemoveLaptopTag_Click(object sender, EventArgs e)
	{
		var t = CMetaTag.Cache.Laptop.Label_OneToOnes;
		var temp = new CLabel_OneToOneList(t);
        foreach (var i in temp)
            i.PhotoHash.Bucket = EImgBucket.None;

        Response.Redirect(Request.RawUrl);
    }
    protected void btnXrated_Click(object sender, EventArgs e)
    {
        var temp = new List<Guid>(SelectedGuids);
        foreach (var i in temp)
        {
            CPhotoHash.Cache.GetById(i).Bucket = EImgBucket.XRated;
            SelectedGuids.Remove(i);
        }
		CSession.PageMessage = string.Concat(temp.Count + " marked as x-rated");
        Response.Redirect(Request.RawUrl);
    }
    protected void btnDelete_Click(object sender, EventArgs e)
    {

        var temp = new List<Guid>(SelectedGuids);
        foreach (var i in temp)
        {
            CPhotoHash.Cache.GetById(i).Bucket = EImgBucket.Deleted;
            SelectedGuids.Remove(i);
        }
        CSession.PageMessage = string.Concat(temp.Count + " marked as deleted");
        Response.Redirect(Request.RawUrl);
    }
    protected void btnRemoveLaptopTagAll_Click(object sender, EventArgs e)
    {
        CMetaTag.Cache.Laptop.Label_OneToOnes.DeleteAll();
        Response.Redirect(Request.RawUrl);
    }
    #endregion
}